package tool.model;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import tool.model.cfg.EntryNode;

public class DU_Path {
	//保存循环开始节点,防止出现死循环
    private LinkedList<GraphNode> cycleVisited = new LinkedList<>();
    
    //保存每个函数的所有路径
    private ArrayList<ArrayList<String>> allPath = new ArrayList<>();
    //把每个函数的路径汇总
    private Map<String, ArrayList<ArrayList<String>>> allPaths = new HashMap();
    
    //把所有变量define所在的全部节点保存
    public static Map<String, ArrayList<String>> allDefNodes = new HashMap();
    //把所有变量use所在的全部节点保存
    public static Map<String, ArrayList<String>> allUseNodes = new HashMap();
    
    //汇总这些map
    private Map<String,Map> mapList = new HashMap();
        
    public static ArrayList<String> findDU(Map<String, ArrayList<ArrayList<String>>> pathMap,String funcName,
    		String startNode,String endNode,ArrayList<String> resultList){
    	//System.out.println("startNode:"+startNode+";endNode:"+endNode);
    	ArrayList<ArrayList<String>> allpath = pathMap.get(funcName);
    	for (ArrayList<String> arrayList : allpath) {
    		String result = "";
    		boolean flag = false;
			for (int i=0;i<arrayList.size();i++) {
				String id = arrayList.get(i);
				if(id.equals(startNode)){
					flag = true;
				}
				if(id.equals(endNode)){
					result = result + id;//最后一个元素
					if(!resultList.contains(result) && flag) resultList.add(result);
					flag = false;
					break;
				}
				if(flag) result = result + id + "->";
			}
		}
    	return resultList;
    }
    public ArrayList<String> findDUs(Map<String, ArrayList<ArrayList<String>>> pathMap,Map<String, ArrayList<String>> defMap,
    		Map<String, ArrayList<String>> useMap,String funcName,String defuseName){
    	ArrayList<String> defNodeList = defMap.get(defuseName);
    	ArrayList<String> useNodeList = useMap.get(defuseName);
    	ArrayList<String> resultList = new ArrayList<>();
    	for (String startNode : defNodeList) {
    		for (String endNode : useNodeList) {
    			resultList = findDU(pathMap,funcName,startNode,endNode,resultList);
    		}
		}
    	return resultList;
    }
	public Map createGraph(List<EntryNode> cfgs) {
    	for(EntryNode entryNode : cfgs) {
    		createNodes(entryNode);
    		cycleVisited = new LinkedList<>();
    		if(!entryNode.getName().contains("全局定义")) 
    			allPaths.put(entryNode.getName().split("\n")[1], allPath);
    		allPath = new ArrayList<>();
    	}
    	mapList.put("allPaths", allPaths);
    	mapList.put("allDefNodes", allDefNodes);
    	mapList.put("allUseNodes", allUseNodes);
    	return mapList;

    }
	private void createNodes(EntryNode entryNode) {
        String idStr = "";
    	createNode(entryNode,idStr);
    	cycleVisited.add(entryNode);
    }

    private void createNode(GraphNode cfgNode,String idStr) {
    	System.out.println("cfgNodeId="+cfgNode.getId()+";SuccessorsSize="+cfgNode.getSuccessors().size());
    	findAllDefUse(cfgNode.getName(),cfgNode.getId()+"");
    	idStr = idStr + cfgNode.getId() + ",";
    	for(GraphNode graphNode : cfgNode.getSuccessors()) {
        	System.out.println("id="+graphNode.id);
        	if(graphNode.getName().contains("While开始")||graphNode.getName().contains("For开始")||graphNode.getName().contains("DoWhile开始")){
        		
        		if(!cycleVisited.contains(graphNode)) cycleVisited.push(graphNode);
        		else {
        			String str[] = idStr.split(",");
        			ArrayList<String> onePath = new ArrayList<>();
        			for (String string : str) {
						if(!string.isEmpty()){
							onePath.add(string);
						}
					}
        			allPath.add(onePath);
        	        System.out.println("idStr="+idStr);
        			return;
        		}
        	}
        	createNode(graphNode,idStr);

        }
    	if(cfgNode.getSuccessors().size()==0) {
    		String str[] = idStr.split(",");
			ArrayList<String> onePath = new ArrayList<>();
			for (String string : str) {
				if(!string.isEmpty()){
					onePath.add(string);
				}
			}
			allPath.add(onePath);
            System.out.println("idStr="+idStr);
    	}
    }
    
    public static void findAllDefUse(String text,String id){
    	String str[] = text.split("\n");
    	for(int i=0;i<str.length;i++){
    		if(str[i].length()>9 && str[i].startsWith("def(")){
    			System.out.println("str[i]="+str[i]);
    			String def = str[i].substring(str[i].indexOf("{")+1, str[i].indexOf("}"));
    			String defStr[] = def.split(",");
    			for (String string : defStr) {
    				if(allDefNodes.containsKey(string)){
    					ArrayList<String> idList = allDefNodes.get(string);
    					if(!idList.contains(id)) idList.add(id);
    					allDefNodes.put(string, idList);//相同string会被覆盖
    				}else{
    					ArrayList<String> idList = new ArrayList<>();
    					idList.add(id);
    					allDefNodes.put(string, idList);
    				}
				}
    		}
    		if(str[i].length()>9 && str[i].startsWith("use(")){
    			String use = str[i].substring(str[i].indexOf("{")+1, str[i].indexOf("}"));
    			String useStr[] = use.split(",");
    			for (String string : useStr) {
    				if(allUseNodes.containsKey(string)){
    					ArrayList<String> idList = allUseNodes.get(string);
    					if(!idList.contains(id)) idList.add(id);
    					allUseNodes.put(string, idList);//相同string会被覆盖
    				}else{
    					ArrayList<String> idList = new ArrayList<>();
    					idList.add(id);
    					allUseNodes.put(string, idList);
    				}
				}
    		}
    	}
    }
}
